package com.woniuxy.service.impl;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.woniuxy.entity.Goods;
import com.woniuxy.entity.Role;
import com.woniuxy.entity.vo.GoodsVO;
import com.woniuxy.mapper.GoodsMapper;
import com.woniuxy.service.GoodsService;
import com.woniuxy.service.RoleService;
import com.woniuxy.utils.CustomPage;
import com.woniuxy.utils.ResponseResults;
import com.woniuxy.utils.ResponseState;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.cache.annotation.Caching;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.List;

@Service
public class GoodsServiceImpl implements GoodsService {

    /**
     * Autowired:优先以类型注入，如果以类型无法注入，就通过名字注入
     * Resource：与上面相反
     * 一般推荐使用@Resource注解
     * */

    @Resource
    private GoodsMapper goodsMapper;

    @Resource
    private RoleService roleService;

    @Value("${server.port}")
    private int port;  // 这里的属性port的值，就是服务器的端口号8081


    /**
     * 代码规范
     * controller 只做接受请求、返回数据的工作
     * service  做数据封装工作，因此返回值要和controller的返回值一致
     * */

    @Cacheable(value = "goods", key = "#categoryId") // 将数据缓存到Redis，这里添加“goods”名称是作为key的前缀，方便key的统一管理
    @Override
    public ResponseResults<List<GoodsVO>> findByCategoryId(int categoryId) {
        // 执行sql
        List<GoodsVO> byCategoryId = goodsMapper.findByCategoryId(categoryId);
        // 封装响应体
        ResponseResults<List<GoodsVO>> objectResponseResults = new ResponseResults<>();
        objectResponseResults.setCode(200);
        objectResponseResults.setState(ResponseState.LOGIN_SUCCESS);
        objectResponseResults.setMsg("查询成功");
        objectResponseResults.setData(byCategoryId);
        return objectResponseResults;
    }

//    @Cacheable("getDetailByGid")
    /** 注意：方法参数名要和指定key名中传入的参数名一致 */
    @Cacheable(value = "getDetailByGid", key = "#gid")   // 指定key，就不必通过配置类中的keygenerator去生成，简化写法
    @Override
    public ResponseResults<Goods> getDetailByGid(int gid) {

        Goods data = goodsMapper.getDetailByGid(gid);
        return new ResponseResults<Goods>()
                .setData(data).setCode(200)
                .setMsg("查询成功")
                .setState(ResponseState.LOGIN_SUCCESS);
    }

    @Override
    public int subStock(int id, int num) {

        return goodsMapper.subStock(id,num);
    }

    /**
     * @ CacheEvict：清除redis缓存数据，删除全部以“getDetailByGid”开头的key
     * @ Caching：删除redis缓存数据数组，可以同时删除多个缓存
     * */
    @Caching(evict = {
            //TODO 批量删除
//    @CacheEvict(value = "getDetailByGid", allEntries = true)  // 将数据从redis中删除
            //TODO 精准删除
//            @CacheEvict(value = "getDetailByGid", key = "'com.woniuxy.service.impl.GoodsServiceImpl.getDetailByGid.' + #id"),
            @CacheEvict(value = "getDetailByGid", key = "#gid"),

            // 删除goodlist列表页面的商品缩略图部分
            // TODO 注意：这里的value是@Cacheable中的名称前缀，而非方法名
//            @CacheEvict(value = "goods", key = "'com.woniuxy.service.impl.GoodsServiceImpl.findByCategoryId.' + #categoryId")
            @CacheEvict(value = "goods", key = "#categoryId")
    })

    @Transactional
    @Override
    public ResponseResults<Boolean> delById(int id, int categoryId) {
        boolean result= goodsMapper.delById(id);
        return new ResponseResults<Boolean>()
                .setCode(result ? 200 : 500)
                .setMsg(result ? "删除成功！": "删除失败！")
                .setState(result ? ResponseState.DEL_SUCCESS:ResponseState.DEL_FAIL)
                .setData(result);
    }

    @Override
    public ResponseResults<CustomPage<List<Goods>>> findByUid(int uid, int page, int size) {

        // 1. 通过用户id得到当前用户的基本信息及角色信息
        Role role = roleService.findByUid(uid);

        // 2. 使用pageHelper，设置起始页、大小
        PageHelper.startPage(page, size);

        // 3. 根据角色信息判断查询是查询所有还是只查询该商户的商品信息
        List<Goods> goods =null;
        if (role.getName().equals("admin")){
            // 3.1 管理员：查询所有的商品
            goods = goodsMapper.findAll();
        } else {
            // 3.2 商家：查询当前商家的商品信息
            goods = goodsMapper.findByMid(uid);
        }

        // 4. 得到分页信息
        PageInfo<Goods> pageInfo = new PageInfo<>(goods);
        // 存入
        CustomPage<List<Goods>> customPage = new CustomPage<>();
        customPage.setCurrentPage(page);
        customPage.setSize(size);
        customPage.setTotal(pageInfo.getTotal());
        customPage.setTotalPage(pageInfo.getPages());
        customPage.setData(goods);

        // 依次将接口的返回值的泛型修改为 CustomPage<List<Goods>>
        return new ResponseResults<CustomPage<List<Goods>>>()
                .setCode(200)
                .setState(ResponseState.SELECT_SUCCESS)
                .setData(customPage);
    }

    @Transactional
    @Override
    public ResponseResults<Boolean> update(Goods goods) {
        boolean result = goodsMapper.update(goods);
        return new ResponseResults<Boolean>()
                .setCode(result ? 200:500)
                .setState(result ? ResponseState.UPDATE_SUCCESS:ResponseState.UPDATE_FAIL)
                .setMsg(result ? "更新成功！": "更新失败！")
                .setData(result);
    }

    @Transactional   // 不要忘记添加
    @Override
    public void add(Goods goods) {
        goodsMapper.add(goods);
    }
}
